#include <brpc/server.h>
#include <butil/logging.h>

#include "../common/asr.hpp"      // 语音识别模块封装
#include "../common/etcd.hpp"     // 服务注册模块封装
#include "../common/logger.hpp"   // 日志模块封装
#include "../build/speech.pb.h"   // protobuf框架代码

using namespace mag;
using namespace std;

namespace mag {  
    // SpeechServiceImpl 类用于实现语音识别的具体 RPC 服务
    // 该类提供了 SpeechRecognition 方法来处理语音识别请求
    class SpeechServiceImpl : public mag::SpeechService {
    public:
        // 构造函数，传入 ASRClient 对象，初始化语音识别客户端
        SpeechServiceImpl(const ASRClient::ptr &asr_client)
            : _asr_client(asr_client) {}

        // 析构函数，释放资源
        ~SpeechServiceImpl() {}

        // SpeechRecognition 方法是实际的服务实现，处理语音识别请求
        // controller：用于控制 RPC 调用的执行
        // request：客户端请求的数据，包括语音内容
        // response：服务端返回的响应数据
        // done：调用完成后的回调，用于通知客户端
        void SpeechRecognition(google::protobuf::RpcController* controller,
                               const ::mag::SpeechRecognitionReq* request,
                               ::mag::SpeechRecognitionRsp* response,
                               ::google::protobuf::Closure* done) {
            LOG_DEBUG("收到语音转文字请求！");

            // 使用 brpc::ClosureGuard 确保 RPC 调用完成后会自动执行 done 回调
            brpc::ClosureGuard rpc_guard(done);

            // 1. 提取请求中的语音内容
            // 2. 调用语音识别客户端进行语音识别，获取识别结果
            std::string err;
            std::string res = _asr_client->recognize(request->speech_content(), err);

            // 3. 如果识别失败，设置响应失败信息
            if (res.empty()) {
                LOG_ERROR("{} 语音识别失败！", request->request_id());
                response->set_request_id(request->request_id());
                response->set_success(false);
                response->set_errmsg("语音识别失败:" + err);
                return;
            }

            // 4. 如果识别成功，设置响应内容
            response->set_request_id(request->request_id());
            response->set_success(true);
            response->set_recognition_result(res);
        }

    private:
        ASRClient::ptr _asr_client; // 语音识别客户端
    };

    // SpeechServer 类用于管理整个语音识别服务
    // 包含对 ASRClient 和 Registry 的引用，并负责启动和运行 RPC 服务
    class SpeechServer {
    public:
        using ptr = std::shared_ptr<SpeechServer>;

        // 构造函数，初始化语音识别客户端、服务注册客户端和 RPC 服务器
        SpeechServer(const ASRClient::ptr asr_client,
                     const Registry::ptr &reg_client,
                     const std::shared_ptr<brpc::Server> &server)
            : _asr_client(asr_client), _reg_client(reg_client), _rpc_server(server) {}

        // 析构函数，释放资源
        ~SpeechServer() {}

        // 启动 RPC 服务器，进入事件循环，直到请求停止
        void start() {
            _rpc_server->RunUntilAskedToQuit();
        }

    private:
        ASRClient::ptr _asr_client;        // 语音识别客户端
        Registry::ptr _reg_client;         // 服务注册客户端
        std::shared_ptr<brpc::Server> _rpc_server; // RPC 服务器
    };

    // SpeechServerBuilder 类用于构建语音识别服务的各个组件
    // 该类提供了构建 ASRClient、Registry 和 RPC 服务器的方法
    class SpeechServerBuilder {
    public:
        // 构造语音识别客户端对象
        // app_id、api_key、secret_key：用于初始化语音识别客户端的参数
        void make_asr_object(const std::string &app_id,
                              const std::string &api_key,
                              const std::string &secret_key) {
            _asr_client = std::make_shared<ASRClient>(app_id, api_key, secret_key);
        }

        // 构造服务注册客户端对象
        // reg_host：注册中心的地址
        // service_name：服务名称
        // access_host：服务访问地址
        void make_reg_object(const std::string &reg_host,
                             const std::string &service_name,
                             const std::string &access_host) {
            _reg_client = std::make_shared<Registry>(reg_host);
            _reg_client->registry(service_name, access_host);
        }

        // 构造 RPC 服务器对象并启动服务器
        // port：服务端口，timeout：超时时间，num_threads：线程数
        void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
            // 确保语音识别模块已经初始化
            if (!_asr_client) {
                LOG_ERROR("还未初始化语音识别模块！");
                abort();
            }

            // 创建 brpc::Server 对象
            _rpc_server = std::make_shared<brpc::Server>();

            // 创建 SpeechServiceImpl 对象，并将其添加到 RPC 服务器
            // SpeechServiceImpl 类实现了语音识别服务的具体业务逻辑
            SpeechServiceImpl *speech_service = new SpeechServiceImpl(_asr_client);
            int ret = _rpc_server->AddService(speech_service,
                                              brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
            if (ret == -1) {
                LOG_ERROR("添加Rpc服务失败！");
                abort();
            }

            // 配置 RPC 服务器的选项
            brpc::ServerOptions options;
            options.idle_timeout_sec = timeout;  // 设置空闲超时时间
            options.num_threads = num_threads;   // 设置工作线程数

            // 启动服务器，监听指定端口
            ret = _rpc_server->Start(port, &options);
            if (ret == -1) {
                LOG_ERROR("服务启动失败！");
                abort();
            }
        }

        // 构建并返回 SpeechServer 对象
        // 返回一个包含语音识别客户端、服务注册客户端和 RPC 服务器的完整服务对象
        SpeechServer::ptr build() {
            if (!_asr_client) {
                LOG_ERROR("还未初始化语音识别模块！");
                abort();
            }
            if (!_reg_client) {
                LOG_ERROR("还未初始化服务注册模块！");
                abort();
            }
            if (!_rpc_server) {
                LOG_ERROR("还未初始化RPC服务器模块！");
                abort();
            }
            // 返回构建好的 SpeechServer 对象
            SpeechServer::ptr server = std::make_shared<SpeechServer>(_asr_client, _reg_client, _rpc_server);
            return server;
        }

    private:
        ASRClient::ptr _asr_client;  // 语音识别客户端
        Registry::ptr _reg_client;   // 服务注册客户端
        std::shared_ptr<brpc::Server> _rpc_server; // RPC 服务器
    };
}
